package com.android.baseconfig.data.http.retrofit2.exception;

import android.net.ParseException;
import android.text.TextUtils;

import com.android.baseconfig.R;
import com.android.baseconfig.constact.ComParamContact;
import com.android.baseconfig.data.http.AppNetDelegate;
import com.google.gson.JsonParseException;

import org.apache.http.conn.ConnectTimeoutException;
import org.json.JSONException;

import java.io.EOFException;
import java.net.ConnectException;

import retrofit2.HttpException;


/**
 * ————————————————————————————————
 * Copyright (C) 2014-2017, by het, Shenzhen, All rights reserved.
 * ————————————————————————————————
 * <p>
 * <p>描述：</p>
 * 名称:  <br>
 * 作者: uuxia<br>
 * 版本: 1.0<br>
 * 日期: 2017/2/22 12:42<br>
 **/
public class ApiException extends RuntimeException {
    //业务字段code
    public int code;
    //http状态码
    public int httpcode;
    //错误信息
    public String msg;

    public String displayMessage;


    public ApiException(String detailMessage) {
        super(detailMessage);
    }

    public ApiException(int code, String detailMessage) {
        super(detailMessage);
        this.code = code;
        setDisplayMessage(detailMessage);
        setDisplayMessage("detail:"+detailMessage);//只是为了追踪从哪个地方抛出的详细日志信息；
        this.msg = detailMessage;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public ApiException(String detailMessage, Throwable throwable) {
        super(detailMessage, throwable);
    }

    public String getDisplayMessage() {
        return displayMessage;
    }

    public void setDisplayMessage(String msg) {
        String message= TextUtils.isEmpty(getMessage())?"":"message:"+getMessage()+",";
        this.displayMessage = msg + "("+message+"code:" + code + ")";
    }

    public ApiException(Throwable throwable) {
        super(throwable);
    }


    public ApiException(Throwable throwable, int code) {
        super(throwable);
        this.code = code;
        this.msg = throwable.getMessage();
        setDisplayMessage(throwable.getMessage());
        setDisplayMessage(throwable.getMessage()+",throwable="+throwable.toString());//只是为了追踪从哪个地方抛出的详细日志信息；
    }

    public static boolean isOk(int code) {
        if (isSucessCode(code) || isPublicIgnoreCode(code)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * code == 0表示接口调用成功
     *
     * @param code
     * @return
     */
    public static boolean isSucessCode(int code) {
        return code == ComParamContact.Code.HTTP_SUCESS ? true : false;
    }

    /**
     * 公共模块统一处理的异常code
     *
     * @param code
     * @return
     */
    public static boolean isPublicIgnoreCode(int code) {
        switch (code) {
            case ComParamContact.Code.DEVICE_NO_BIND://设备未绑定
            case ComParamContact.Code.TIMESTAMP_ERROR:////timestamp过期
            case ComParamContact.Code.ACCESS_TOKEN_EXPIRED:////AccessToken错误或已过期
            case ComParamContact.Code.REFRESH_TOKEN_EXPIRED:////RefreshToken错误或已过期
            case ComParamContact.Code.OTHER_PHONE_LOGINED: //帐号在其它手机已登录
            case ComParamContact.Code.ERROR_SIGN://签名错误
            case ComParamContact.Code.DEVICE_OFF_LINE://设备不在线
            case ComParamContact.Code.NO_DEVICE://设备不存在
                return true;
            default:
                return false;

        }
    }

    public int getCode() {
        return code;
    }

    @Override
    public String getMessage() {
        return msg;
    }

    public static ApiException handleException(Throwable e) {
        ApiException ex;
        if (e instanceof HttpException) {
            HttpException httpException = (HttpException) e;
            String errorBodyMsg="",rawResponseMsg="",url ="";
            try {
                errorBodyMsg=httpException.response().errorBody().string();
                //rawResponseMsg=httpException.response().toString();
                rawResponseMsg=httpException.response().raw().toString();
                //rawResponseMsg=httpException.response().raw().request().url().toString();
                url = httpException.response().raw().request().url().toString();

            }catch (Exception e1){
                e1.printStackTrace();
            }

            ex = new ApiException(e, HttpErrorCode.HTTP_ERROR);
            ex.setDisplayMessage(url+","+rawResponseMsg+","+errorBodyMsg);
            ex.httpcode = httpException.code();
            switch (httpException.code()) {
                case HttpErrorCode.HttpStatusCode.UNAUTHORIZED:
                    ex.msg = HttpErrorCode.HttpStatusCode.UNAUTHORIZED_STRING;
                    ex.msg = HttpErrorCode.HttpStatusCode.SERVER_ERROR_TRY;
                    break;
                case HttpErrorCode.HttpStatusCode.FORBIDDEN:
                    ex.msg = HttpErrorCode.HttpStatusCode.FORBIDDEN_STRING;
                    ex.msg = HttpErrorCode.HttpStatusCode.SERVER_ERROR_TRY;
                    break;
                case HttpErrorCode.HttpStatusCode.NOT_FOUND:
                    ex.msg = HttpErrorCode.HttpStatusCode.NOT_FOUND_STRING;
                    ex.msg = HttpErrorCode.HttpStatusCode.SERVER_ERROR_TRY;
                    break;
                case HttpErrorCode.HttpStatusCode.REQUEST_TIMEOUT:
                    ex.msg = HttpErrorCode.HttpStatusCode.REQUEST_TIMEOUT_STRING;
                    ex.msg = HttpErrorCode.HttpStatusCode.SERVER_ERROR_TRY;
                    break;
                case HttpErrorCode.HttpStatusCode.GATEWAY_TIMEOUT:
                    ex.msg = HttpErrorCode.HttpStatusCode.GATEWAY_TIMEOUT_STRING;
                    ex.msg = HttpErrorCode.HttpStatusCode.SERVER_ERROR_TRY;
                    break;
                case HttpErrorCode.HttpStatusCode.INTERNAL_SERVER_ERROR:
                    ex.msg = HttpErrorCode.HttpStatusCode.INTERNAL_SERVER_ERROR_STRING;
                    ex.msg = HttpErrorCode.HttpStatusCode.SERVER_ERROR_TRY;
                    break;
                case HttpErrorCode.HttpStatusCode.BAD_GATEWAY:
                    ex.msg = HttpErrorCode.HttpStatusCode.BAD_GATEWAY_STRING;
                    ex.msg = HttpErrorCode.HttpStatusCode.SERVER_ERROR_TRY;
                    break;
                case HttpErrorCode.HttpStatusCode.SERVICE_UNAVAILABLE:
                    ex.msg = HttpErrorCode.HttpStatusCode.SERVICE_UNAVAILABLE_STRING;
                    ex.msg = HttpErrorCode.HttpStatusCode.SERVER_ERROR_TRY;
                    break;
                default:
                    ex.msg = HttpErrorCode.HttpStatusCode.UNKNOW_STRING;
                    ex.msg = HttpErrorCode.HttpStatusCode.SERVER_ERROR_TRY;
                    break;
            }
            return ex;
        } else if (e instanceof ApiException) {
            ApiException resultException = (ApiException) e;
            switch (resultException.getCode()) {
                case ComParamContact.Code.NO_ACCESS_TOKEN:
                    resultException.msg = AppNetDelegate.getAppContext().getString(R.string.common_basic_no_access_token);
                    break;
                default:
//                    resultException.msg = AppNetDelegate.getAppContext().getResources().getString(R.string.common_basic_default_api_exception)
//                            + " " + resultException.getCode();
                    break;
            }
            //resultException.setDisplayMessage(e.getMessage());
            return resultException;
        } else if (e instanceof JsonParseException
                || e instanceof JSONException
                || e instanceof ParseException|| e instanceof EOFException) {
            ex = new ApiException(e, HttpErrorCode.PARSE_ERROR);
            ex.msg = HttpErrorCode.PARSE_ERROR_STRING;
            ex.msg = HttpErrorCode.HttpStatusCode.SERVER_ERROR_TRY;
            return ex;
        } else if (e instanceof ConnectException) {
            ex = new ApiException(e, HttpErrorCode.NETWORD_ERROR);
            ex.msg = HttpErrorCode.NETWORD_ERROR_STRING;
            return ex;
        } else if (e instanceof javax.net.ssl.SSLHandshakeException) {
            ex = new ApiException(e, HttpErrorCode.SSL_ERROR);
            ex.msg = HttpErrorCode.SSL_ERROR_STRING;
            return ex;
        } else if (e instanceof ConnectTimeoutException) {
            ex = new ApiException(e, HttpErrorCode.TIMEOUT_ERROR);
            ex.msg = HttpErrorCode.TIMEOUT_ERROR_ERRORSTRING;
            return ex;
        } else if (e instanceof java.net.SocketTimeoutException) {
            ex = new ApiException(e, HttpErrorCode.TIMEOUT_ERROR);
            ex.msg = HttpErrorCode.TIMEOUT_ERROR_ERRORSTRING;
            return ex;
        } else if (e instanceof java.net.UnknownHostException) {
            ex = new ApiException(e, HttpErrorCode.NETWORD_ERROR);
            ex.msg = HttpErrorCode.NETWORD_ERROR_STRING;
            return ex;
        } else {
            ex = new ApiException(e, HttpErrorCode.UNKNOWN);
            ex.msg = HttpErrorCode.UNKNOWN_STRING;
            ex.setDisplayMessage(ex.msg+",e="+e.toString());//只是为了追踪从哪个地方抛出的详细日志信息；
            return ex;
        }
    }
}
